package com.hzw.saas.common.storage.service;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

import com.hzw.saas.common.storage.pojo.FileStorage;
import com.hzw.saas.common.util.enums.ConflictModeEnum;
import cn.hutool.core.io.IORuntimeException;

/**
 * 文件存储接口
 * 此处文件和目录统称为文件
 * 路径参数均支持绝对路径和相对路径，相对路径的根路径为classpath
 *
 * @author zzl
 * @since 04/20/2021
 */
public interface IFileStorageService {

    /**
     * 获取文件
     *
     * @param path 文件路径
     * @return 文件对象
     */
    File getFile(String path);

    /**
     * 获取文件
     *
     * @param supPath  文件父目录
     * @param fileName 文件名
     * @return 文件对象
     */
    File getFile(String supPath, String fileName);

    /**
     * 文件是否存在
     *
     * @param path 文件路径
     * @return true-存在，false-不存在
     */
    boolean exist(String path);

    /**
     * 文件是否存在
     *
     * @param supPath  文件父目录
     * @param fileName 文件名
     * @return true-存在，false-不存在
     */
    boolean exist(String supPath, String fileName);

    /**
     * 获取文件或目录（递归获取子文件）大小
     *
     * @param path 文件路径
     * @return 文件长度(byte)，当文件不存在时，返回负数
     */
    long getLength(String path);

    /**
     * 获取文件或目录（递归获取子文件）大小
     *
     * @param supPath  文件父目录
     * @param fileName 文件名
     * @return 文件长度(byte)，当文件不存在时，返回负数
     */
    long getLength(String supPath, String fileName);

    /**
     * 获取文件摘要值
     *
     * @param path       文件路径
     * @param digestType 摘要类型，支持md5,sha1,sha256。为空或其他则默认使用md5
     * @return 文件摘要16进制字符串，当文件不存在时，空
     */
    String getDigest(String path, String digestType);

    /**
     * 获取文件MD5值
     *
     * @param supPath    文件目录
     * @param fileName   文件名
     * @param digestType 摘要类型，支持md5,sha1,sha256。为空或其他则默认使用md5
     * @return 文件摘要16进制字符串，当文件不存在时，空
     */
    String getDigest(String supPath, String fileName, String digestType);

    /**
     * 创建目录
     * 支持多级创建
     *
     * @param path 目录路径
     * @return 创建的目录
     */
    File mkdir(String path);

    /**
     * 创建目录
     * 支持多级创建
     *
     * @param supPath    文件目录
     * @param folderName 目录名称
     * @return 创建的目录
     * @throws IORuntimeException e
     */
    File mkdir(String supPath, String folderName) throws IORuntimeException;

    /**
     * 重命名文件
     *
     * @param supPath 父路径
     * @param srcName 原文件名
     * @param tarName 新文件名
     * @param mode    同名冲突解决方式
     * @return 重命名的文件
     * @throws IORuntimeException check FileAlreadyExistsException，FileNotFoundException
     */
    File rename(String supPath, String srcName, String tarName, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 重命名文件
     *
     * @param srcPath 原文件路径
     * @param tarName 新文件名
     * @param mode    名冲突解决方式
     * @return 重命名的文件
     * @throws IORuntimeException check FileAlreadyExistsException，FileNotFoundException
     */
    File rename(String srcPath, String tarName, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 复制文件
     *
     * @param srcPath 文件原路径
     * @param tarPath 文件目标路径
     * @param mode    同名冲突解决方式
     * @return 复制的文件
     * @throws IORuntimeException check FileAlreadyExistsException，FileNotFoundException
     */
    File copy(String srcPath, String tarPath, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 移动文件
     *
     * @param srcPath 文件原路径
     * @param tarPath 文件目标路径
     * @param mode    同名冲突解决方式
     * @return 移动后的文件
     * @throws IORuntimeException check FileAlreadyExistsException，FileNotFoundException
     */
    File move(String srcPath, String tarPath, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 移除文件
     *
     * @param supPath  文件目录
     * @param fileName 文件名
     * @throws IORuntimeException check FileNotFoundException
     */
    void delete(String supPath, String fileName, boolean rf) throws IORuntimeException;

    /**
     * 移除文件
     *
     * @param path 文件路径
     * @param rf   强制删除(文件夹存在文件时)
     * @throws IORuntimeException check FileNotFoundException
     */
    void delete(String path, boolean rf) throws IORuntimeException;

    /**
     * 保存文件
     *
     * @param tarFileInfo 文件信息
     * @param srcIns      文件输入流
     * @param mode        同名冲突解决方式
     * @return 保存的文件
     * @throws IORuntimeException check FileAlreadyExistsException
     */
    File write(FileStorage tarFileInfo, InputStream srcIns, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 保存文件
     *
     * @param tarFileInfo 文件信息
     * @param srcFile     待保存文件
     * @param mode        同名冲突解决方式
     * @return 保存的文件
     * @throws IORuntimeException check FileAlreadyExistsException
     */
    File write(FileStorage tarFileInfo, File srcFile, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 保存文件
     *
     * @param tarFileInfo 文件信息
     * @param data        文件数据
     * @param mode        同名冲突解决方式
     * @return 保存的文件
     * @throws IORuntimeException check FileAlreadyExistsException
     */
    File write(FileStorage tarFileInfo, byte[] data, ConflictModeEnum mode) throws IORuntimeException;

    /**
     * 读取文件
     *
     * @param path      文件路径
     * @param os        输出流
     * @param skipBytes 跳过字节数
     * @throws IORuntimeException check FileNotFoundException
     */
    void read(String path, OutputStream os, long skipBytes) throws IORuntimeException;

}
